package org.voovan.jinflux.model;

import com.sun.org.apache.bcel.internal.generic.NEW;
import org.voovan.jinflux.Jinflux;
import org.voovan.tools.json.JSON;
import org.voovan.tools.log.Logger;
import org.voovan.tools.reflect.TReflect;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 类文字命名
 *
 * @author: helyho
 * voovan-Influxdb Framework.
 * WebSite: https://github.com/helyho/voovan-Influxdb
 * Licence: Apache v2 License
 */
public class Resp {
    private List<Result> results;
    private String error;

    public boolean hasResults(){
        return results!=null && results.size() > 0;
    }

    public String getError() {
        return error;
    }

    public List<Result> getResults() {
        return results;
    }

    public List<Map<String, Object>> getMaps(int index) {
        if(results!=null && results.size()<=index) {
            return null;
        }

        Result result = results.get(index);

        if(result.getSeries()==null || result.getSeries().isEmpty()) {
            return null;
        }

        ArrayList<Map<String, Object>> retData = new ArrayList<Map<String, Object>>();

        try {
            List<String> columns = result.getSeries().get(0).getColumns();
            columns = getOriginColumn(columns);
            List<List<Object>> values = result.getSeries().get(0).getValues();
            for (int i = 0; i < values.size(); i++) {
                Map<String, Object> recordMap = new HashMap<String, Object>();
                for (int j = 0; j < columns.size(); j++) {
                    List<Object> data = values.get(i);
                    if (data.size() == columns.size()) {
                        recordMap.put(columns.get(j), data.get(j));
                    }
                }

                if(!recordMap.isEmpty()) {
                    recordMap.put("time", Jinflux.parseNanoTime(recordMap.get("time").toString()));
                    retData.add(recordMap);
                }
            }

            return retData;
        } catch (Exception e) {
            Logger.error("Resp.getMap failed: " + JSON.toJSON(this), e);
            return null;
        }
    }

    public List<String> getOriginColumn(List<String> columns){
        if(columns.size() > 1) {
            String columnName = columns.get(1);
            int index = columnName.indexOf("_");
            if(index > 0) {
                String functionName = columnName.substring(0, index);
                List<String> newColumns = new ArrayList<String>();
                for(String column : columns) {
                    if(column.startsWith(functionName)) {
                        newColumns.add(column.replace(functionName + "_", ""));
                    } else if(column.equals("time")) {
                        newColumns.add(column);
                        continue;
                    } else {
                        newColumns.clear();
                        newColumns = null;
                        return columns;
                    }
                }
                return newColumns;
            }
        }

        return columns;

    }

    public <T> List<T> getObjects(int index, Class<T> clazz) {
        List<Map<String, Object>> recordMaps = getMaps(index);

        if(recordMaps == null) {
            return null;
        }

        ArrayList<T> retData = new ArrayList<T>();

        for(Map<String, Object> recordMap : recordMaps) {
            try {
                retData.add((T)TReflect.getObjectFromMap(clazz, recordMap, false));
            } catch (Exception e) {
                Logger.error("Parser failed: " + JSON.toJSON(recordMap), e);
            }
        }

        return retData;
    }
}
